package org.slusk.thynwor.ui;

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTable;
import javax.swing.JTextPane;
import javax.swing.JToggleButton;
import javax.swing.ListSelectionModel;

import net.miginfocom.swing.MigLayout;

import org.slusk.thynwor.corestructures.Drone;
import org.slusk.thynwor.corestructures.Entity;
import org.slusk.thynwor.corestructures.Environment;
import org.slusk.thynwor.corestructures.GridCell;
import org.slusk.thynwor.corestructures.GridMap;
import org.slusk.thynwor.corestructures.IWorker;
import org.slusk.thynwor.corestructures.Manager;
import org.slusk.thynwor.corestructures.Region;
import org.slusk.thynwor.corestructures.Resource;
import org.slusk.thynwor.util.Coordinates;
import org.slusk.thynwor.util.Direction;

import java.awt.Color;
import java.util.LinkedList;

public class ThynworWindow implements IThynworWindow {

	private Environment environment;
	private Resource selectedTask;
	private JFrame frmNnnbenvironment;
	private JTable table;
	private JButton btnNw;
	private JButton button;
	private JButton button_1;
	private JButton btnV;
	private JButton button_2;
	private JButton btnSw;
	private JButton btnNe;
	private JButton btnSe;
	private JTextPane textPane;
	private JButton button_3;
	private JToggleButton tglbtnInteract;
	private JToggleButton tglbtnToggleSim;
	private JScrollPane scrollPane;
	private JButton btnReset;
	private static JMenuBar menuBar;
	private static JMenu mnEnvironment;
	private static JMenuItem mntmCreateNewEnvironment;
	private JMenuItem mntmShowStats;
	private final Action action = new SwingAction();
	private JMenuItem mntmSelectNetwork;
	private JMenuItem mntmOptions;
	private JButton btnShowStats;
	private JButton btnSignallist;
	private JButton btnTestboin;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					ThynworWindow window = new ThynworWindow();
					window.frmNnnbenvironment.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	public void createRandomLayout() {
		environment.setUseRandomLayout(true);
		environment.resetLayout();
		getTable().setModel(environment.getMap());
		getTable().repaint();
		displayGridCellInfo();
	}
	
	/**
	 * Create the application.
	 */
	public ThynworWindow() {
		environment = new Environment();
		initialize();
	}
	

	public ThynworWindow(Environment env) {
		environment = env;
		initialize();
		//this.getTable().setModel(environment.getMap());
		
		this.getFrame().setVisible(true);
//		this.getFrame().pack();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frmNnnbenvironment = new JFrame();
		frmNnnbenvironment.setTitle("Thynwor Environment");
		frmNnnbenvironment.setBounds(10, 10, 609, 750);
		frmNnnbenvironment.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frmNnnbenvironment.getContentPane().setLayout(new MigLayout("", "[grow][][][][][][][]", "[grow][grow][][][][][][][][][]"));
		
		table = new JTable();
		table.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				displayGridCellInfo();
			}
		});
		table.setFont(new Font("Monospaced", Font.PLAIN, 12));
		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		table.setRowSelectionAllowed(false);
		frmNnnbenvironment.getContentPane().add(table, "cell 0 0 8 2,grow");
		
		btnNw = new JButton("NW");
		btnNw.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				directSelectedEntity(Direction.NW);
			}
		});
		
		scrollPane = new JScrollPane();
		scrollPane.setMinimumSize(new Dimension(50, 50));
		frmNnnbenvironment.getContentPane().add(scrollPane, "cell 0 2 4 8,grow");
		
		textPane = new JTextPane();
		textPane.setForeground(Color.GREEN);
		textPane.setBackground(Color.BLACK);
		scrollPane.setViewportView(textPane);
		textPane.setEditable(false);
		btnNw.setFont(new Font("Monospaced", Font.BOLD, 12));
		frmNnnbenvironment.getContentPane().add(btnNw, "cell 4 2,alignx right");
		
		button = new JButton("^");
		button.setMnemonic('w');
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				directSelectedEntity(Direction.N);
			}
		});
		button.setFont(new Font("Monospaced", Font.BOLD, 12));
		frmNnnbenvironment.getContentPane().add(button, "cell 5 2,alignx center");
		
		btnNe = new JButton("NE");
		btnNe.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				directSelectedEntity(Direction.NE);
			}
		});
		btnNe.setFont(new Font("Monospaced", Font.BOLD, 12));
		frmNnnbenvironment.getContentPane().add(btnNe, "cell 6 2,alignx left");
		
		button_2 = new JButton("<");
		button_2.setMnemonic('a');
		button_2.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				directSelectedEntity(Direction.W);
			}
		});
		button_2.setFont(new Font("Monospaced", Font.BOLD, 12));
		frmNnnbenvironment.getContentPane().add(button_2, "cell 4 3,alignx right");
		
		button_3 = new JButton("*");
		button_3.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				environment.timeStep();
				displayGridCellInfo();
				table.repaint();
			}
		});
		button_3.setFont(new Font("Monospaced", Font.BOLD, 12));
		frmNnnbenvironment.getContentPane().add(button_3, "cell 5 3,alignx center");
		
		button_1 = new JButton(">");
		button_1.setMnemonic('d');
		button_1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				directSelectedEntity(Direction.E);
			}
		});
		button_1.setFont(new Font("Monospaced", Font.BOLD, 12));
		frmNnnbenvironment.getContentPane().add(button_1, "cell 6 3");
		
		btnSw = new JButton("SW");
		btnSw.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				directSelectedEntity(Direction.SW);
			}
		});
		btnSw.setFont(new Font("Monospaced", Font.BOLD, 12));
		frmNnnbenvironment.getContentPane().add(btnSw, "cell 4 4,alignx right");
		
		btnV = new JButton("v");
		btnV.setMnemonic('s');
		btnV.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				directSelectedEntity(Direction.S);
			}
		});
		btnV.setFont(new Font("Monospaced", Font.BOLD, 12));
		frmNnnbenvironment.getContentPane().add(btnV, "cell 5 4,alignx center");
		
		btnSe = new JButton("SE");
		btnSe.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				directSelectedEntity(Direction.SE);
			}
		});
		btnSe.setFont(new Font("Monospaced", Font.BOLD, 12));
		frmNnnbenvironment.getContentPane().add(btnSe, "cell 6 4,alignx left");
		
		tglbtnInteract = new JToggleButton("Interact");
		frmNnnbenvironment.getContentPane().add(tglbtnInteract, "cell 4 5,growx");
		
		tglbtnToggleSim = new JToggleButton("Toggle Sim");
		tglbtnToggleSim.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				toggleRunSim();
			}
		});
		
		btnReset = new JButton("Reset");
		btnReset.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if (environment.getIsSimRunning()) environment.stopSim();
				environment.resetLayout();
				getTable().setModel(environment.getMap());
				getTable().repaint();
				displayGridCellInfo();
			}
		});
		frmNnnbenvironment.getContentPane().add(btnReset, "flowy,cell 6 5,grow");
		frmNnnbenvironment.getContentPane().add(tglbtnToggleSim, "cell 4 6,growx");
		
		btnShowStats = new JButton("Show Stats");
		btnShowStats.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				showStats();
			}
		});
		
		btnSignallist = new JButton("SignalList");
		btnSignallist.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				
				LinkedList<Coordinates> list = environment.buildSignalCoordinatesList();
				LinkedList<Coordinates> list2 = environment.buildSignalCoordinatesListInRange(getSelectedCoordinates(), 5);
				StringBuilder sb = new StringBuilder();
				for (Coordinates c: list) {
					sb.append(c);
					sb.append("\n");
				}
				sb.append("\n");
				for (Coordinates c: list2) {
					sb.append(c);
					sb.append("\n");
				}
				setDisplayText(sb.toString());
			}
		});
		frmNnnbenvironment.getContentPane().add(btnSignallist, "cell 6 6");
		frmNnnbenvironment.getContentPane().add(btnShowStats, "cell 4 7,grow");
		
		btnTestboin = new JButton("TestSatsIn");
		btnTestboin.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				testBo4Input();
			}
		});
		frmNnnbenvironment.getContentPane().add(btnTestboin, "cell 6 7");
		
		JSeparator separator = new JSeparator();
		frmNnnbenvironment.getContentPane().add(separator, "cell 7 10");
		
		getTable().setModel(environment.getMap());
				
		menuBar = new JMenuBar();
		frmNnnbenvironment.setJMenuBar(menuBar);
		
		mnEnvironment = new JMenu("Environment");
		menuBar.add(mnEnvironment);
		
		mntmCreateNewEnvironment = new JMenuItem("Create Random Layout");
		mntmCreateNewEnvironment.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				createRandomLayout();
			}
		});
		mnEnvironment.add(mntmCreateNewEnvironment);
		
		mntmShowStats = new JMenuItem("Show stats");
		mntmShowStats.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				showStats();
			}
		});
		
		mntmSelectNetwork = new JMenuItem("Select Network...");
		mntmSelectNetwork.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				environment.showNetSelectionDialog();
			}
		});
		mnEnvironment.add(mntmSelectNetwork);
		
		mntmOptions = new JMenuItem("Options");
		mntmOptions.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				environment.showOptionsDialog();
			}
		});
		mnEnvironment.add(mntmOptions);
		mnEnvironment.add(mntmShowStats);
	}

	protected void testBo4Input() {
		Entity e = getSelectedEntity();
		if (null != e) {
			try {
				Drone d = (Drone) e;
				d.testSasasInputs();
			} catch (ClassCastException x) {
				// do nothing.
			} // All other problems should throw.
		}
	}
	
	/* (non-Javadoc)
	 * @see org.slusk.thynwor.ui.IThynworWindow#dispose()
	 */
	@Override
	public void dispose() {
		this.getFrame().setVisible(false);
		this.getFrame().dispose();
		this.frmNnnbenvironment = null;
	}

	protected void showStats() {
		textPane.setText(environment.getStatsString());
	}

	public void displayGridCellInfo() {
		int x = table.getSelectedColumn();
		int y = table.getSelectedRow();
		if (environment.getMap().isInBounds(new Coordinates(x, y))) {
			GridCell gc = environment.getMap().get(x, y);
		
			StringBuilder sb = new StringBuilder();
			sb.append("Coordinates: ");
			sb.append(x);
			sb.append(",");
			sb.append(y);
			sb.append("\n");
			sb.append(gc.getInfo());
			sb.append("\n\n");
			for (Region r : environment.getMap().getRegionsAt(x, y)) {
				sb.append(r.toString());
			}
			textPane.setText(sb.toString());
			
			textPane.setCaretPosition(0);
		}
	}

	public Coordinates getSelectedCoordinates() {
		int x = table.getSelectedColumn();
		int y = table.getSelectedRow();
		Coordinates c = new Coordinates(x, y);
		if (environment.getMap().isInBounds(c)) return c;
		return null;
	}
	
	public void setDisplayText(String msg) {
		textPane.setText(msg);
		textPane.setCaretPosition(0);
	}
	
	protected void directSelectedEntity(Direction direction) {
		Entity entity = getSelectedEntity();
		if (null != entity) {
			if (tglbtnInteract.isSelected() && entity instanceof IWorker && !environment.getMap().isFree(GridMap.directionToCoordinates(direction, entity.getCoordinates()))) {
					((IWorker)entity).interact(direction);
			} else {
				entity.move(direction);
			}
			table.repaint();
			table.changeSelection(entity.getCoordinates().y, entity.getCoordinates().x, false, false);
		}
		table.requestFocusInWindow();
	}

	public JFrame getFrame() {
		return frmNnnbenvironment;
	}
	public JTable getTable() {
		return table;
	}
	protected JToggleButton getTglbtnInteract() {
		return tglbtnInteract;
	}
	
	public Entity getSelectedEntity() {
		int x = table.getSelectedColumn();
		int y = table.getSelectedRow();
		Entity entity = environment.getMap().get(x, y).getContents();
		return entity;
	}

	private void toggleRunSim() {
		if (tglbtnToggleSim.isSelected()) {
			environment.startSim();
		} else {
			environment.stopSim();
		}
	}
	private class SwingAction extends AbstractAction {
		public SwingAction() {
			putValue(NAME, "SwingAction");
			putValue(SHORT_DESCRIPTION, "Some short description");
		}
		public void actionPerformed(ActionEvent e) {
		}
	}
	/* (non-Javadoc)
	 * @see org.slusk.thynwor.ui.IThynworWindow#setMap(org.slusk.thynwor.corestructures.GridMap)
	 */
	@Override
	public void setMap(GridMap map) {
		getTable().setModel(map);
		getTable().setDefaultRenderer(Object.class, map.getCellRenderer());
	}

	/* (non-Javadoc)
	 * @see org.slusk.thynwor.ui.IThynworWindow#update()
	 */
	@Override
	public void update() {
		displayGridCellInfo();
		getTable().repaint();
	}
}
